﻿/*
   Copyright 2012 University of Southampton

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace uk.ac.soton.ses.ExperimentDataFilesWebPart
{
    [ToolboxItemAttribute(false)]
    public class ExperimentDataFilesWebPart : WebPart, IWebPartField, IHDCWebPartSelectedExperimentDataFileID
    {
        // Visual Studio might automatically update this path when you change the Visual Web Part project item.
        private const string _ascxPath = @"~/_CONTROLTEMPLATES/uk.ac.soton.ses/HDCUserControls/ExperimentDataFilesWebPartUserControl.ascx";
        //private RowCallback _rowDataCallback = null;
        private ExperimentDataFilesWebPartUserControl _control = null;
        private IHDCWebPartSelectedExperimentID _experimentProvider = null;

        private const string _selectedUrl = @"http://localhost:8008/tensile/Specimen 1 Data for Matlab.xlsx";
        private string SelectedUrl
        {
            get
            {
                if (this._control != null && Path.GetExtension(_selectedUrl).ToLower() == "xlsx")
                    return _selectedUrl;
                else
                    return "";
            }
        }

        /// <summary>
        /// Constructor. Nothing needed here at the moment.
        /// </summary>
        public ExperimentDataFilesWebPart()
        {
            DebugMessage("webpart>constructor");
        }

        //Always load the control in OnInit() so we can process postbacks but set it as invisible in case the provider tells us we have no experiment to bind to.
        //We'll make it visible again in OnPreRender as that is the only stage we'll definitely have a provider.
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            this._control = (ExperimentDataFilesWebPartUserControl)Page.LoadControl(_ascxPath);
            this._control.Visible = false;
            this.Controls.Add(this._control);

        }
        /// <summary>
        /// Load the visual control and set up its events
        /// </summary>
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            DebugMessage("webpart>CreateChildControls");
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            //If we have an experiment provider, we'll need to filter the list
            if (this._experimentProvider != null)
            {
                int selectedExperiment = this._experimentProvider.GetSelectedExperimentID();
                if (selectedExperiment > 0)
                {
                    this._control.Visible = true;
                    this._control.DataBindToExperiment(selectedExperiment);
                }
                else
                {
                    //Need to set it to invisible again because we're sometimes getting ignored, probably because of viewstate
                    this._control.Visible = false;
                    this.DisplayMessageLabel("Please select an experiment");
                    //this._control.DataBindWithoutFilter();
                }
            }
            else
            {
                //Need to set it to invisible again because we're sometimes getting ignored, probably because of viewstate
                this._control.Visible = false;
                this.DisplayMessageLabel("No connection. Please connect me to an experiment list.");
                //this._control.DataBindWithoutFilter();
            }
        }

        //---Field data for the selected Excel file to pass to the Excel web part
        [ConnectionProvider("Excel Spreadsheet Url", "WorkbookUrl")]
        public IWebPartField GetConnectionInterface()
        {
            DebugMessage("webpart>GetConnectionInterface");
            return this;
        }
        //IWebPartField members
        public void GetFieldValue(FieldCallback callback)
        {
            callback(this.SelectedUrl);
        }
        PropertyDescriptor IWebPartField.Schema
        {
            get { return TypeDescriptor.GetProperties(this)["SelectedUrl"]; }
        }


        //--ExperimentDataFile ID Connection. We'll just return the ID rather than an object and leave it up to the caller to load the object if they want.
        [ConnectionProvider("Selected row data object", "SelectedExperimentDataFile")]
        public IHDCWebPartSelectedExperimentDataFileID GetExperimentDataFileConnectionInterface()
        {
            DebugMessage("webpart>GetExperimentDataFileConnectionInterface");
            return this;
        }
        public int GetSelectedExperimentDataFileID()
        {
            if (this._control != null)
                return this._control.SelectedRowID;
            else
                return -1;
        }

        //We're a receiver of data too
        [ConnectionConsumer("Selected experiment", "SelectedExperiment")]
        public void SetExperimentConnectionInterface(IHDCWebPartSelectedExperimentID experimentProvider)
        {
            this._experimentProvider = experimentProvider;

            //Don't need to check for null. If we don't have a connection (experimentProvider is null), we don't care as we can just show all data files
        }

        private void DebugMessage(string s)
        {
            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (FileStream fs = File.Open(@"c:\temp\debuglog.log", FileMode.Append, FileAccess.Write, FileShare.Read))
                    using (StreamWriter writer = new StreamWriter(fs))
                    {
                        writer.AutoFlush = true;
                        writer.WriteLine(s);
                        writer.Flush();
                        writer.Close();
                    }
                });
            }
            catch (Exception ex)
            {
                this.DisplayMessageLabel(ex.Message);
            }
        }
        private void DisplayMessageLabel(string error)
        {
            Label messageLabel = new Label();
            Controls.Add(messageLabel);
            messageLabel.Text = error;
        }


    }
}
